package com.yjhh.scala

/**
  * 1. Scala中使用class定义类
  * 2. Scala中使用new ClassName()，构造出类的对象，
  * 3. Scala中如果名称相同，则object中的内容都是class的静态内容，也就是说，object中的内容class都可以在没有实例的情况下直接调用
  * 正应为可以以在没有实例的时候去调用object中的一切内容，所以可以使用object中的特定方法来创建类的实例，这个特定方法就是apply
  * 4. object中的apply方法是class对象生成的工厂方法，用于控制对象的生成
  * 5. 很多框架的代码一般直接调用抽象类的object的apply方法生成类的实例对象
  * 第一：起秘诀在于apply具有类的对象生成的管理权，抽象类是不可以直接实例化的，在apply方法中可以实例化抽象类的子类，以Spark中的
  * 图计算为例，从Spark如计算的代码中可以看出来，GraphImpl的构造也是使用了object GraphImpl的apply方法；
  * 第二：这种方式可以广泛的应用于对于版本迭代或者修改的变化，这可以更高意义的面向接口变成；
  * Scala中没有像java中那样的（static）静态类、方法
  * 6.object ScalaOOP是class ScalaOOP的伴生对象，class ScalaOOP可以直接访问object ScalaOOP的一切内容
  * class ScalaOOP是object ScalaOOP的伴生类，object ScalaOOP可以直接访问class ScalaOOP中的一切内容，private[this]是一个特例。
  * 7. 在定义scala的class的时候可以直接在类名的后边（）里加入类的构造参数，此时在apply方法中也必须有这些参数
  * 8. scala中可以构造很多apply方法
  * 9. scala中的很多集合都是使用apply方式来构造的，Array
  */
class ScalaOOP(age:Int) {

  var name = "TEST"

  def sayHello = {
    println("My name is " + name)
    println(" I am " + age + " years old")
  }

}

object ScalaOOP {

  var number = 0

  def main(args: Array[String]): Unit = {
    val scalaOOP = new ScalaOOP(31)
    scalaOOP.sayHello;

    val scalaOOP1 = ScalaOOP(30)
    scalaOOP1.sayHello;

    ScalaOOP(10)
    ScalaOOP(11)
    ScalaOOP(12)
    ScalaOOP(13)

    Array(1,2,3,4)
  }

  def apply(): ScalaOOP = {
    number = number + 1
    println(number)
    new ScalaOOP(number)
  }

  def apply(age: Int): ScalaOOP = {
    number = number + 1
    println(number)
    new ScalaOOP(age)
  }

}

